home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / os2tools / bnklysrc / btctl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-16  |  32.2 KB  |  796 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software <no-Inc>                   */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          No-Cost<no-tm> Software.                       */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*  Copyright (C) 1987, 1988, 1989 by Robert Hartman and Vincent Perriello  */
  11. /*                                                                          */
  12. /*                                                                          */
  13. /*               This module was written by Vince Perriello                 */
  14. /*                                                                          */
  15. /*                                                                          */
  16. /*                 BinkleyTerm OMMM Control File Generator                  */
  17. /*                                                                          */
  18. /*                                                                          */
  19. /*    For complete  details  of the licensing restrictions, please refer    */
  20. /*    to the License  agreement,  which  is published in its entirety in    */
  21. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.210.    */
  22. /*                                                                          */
  23. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  24. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  25. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  26. /*    NOT HAVE THESE FILES,  YOU SHOULD  IMMEDIATELY CONTACT THE AUTHORS    */
  27. /*    AT THE  ADDRESSES LISTED BELOW.  IN NO EVENT SHOULD YOU PROCEED TO    */
  28. /*    USE   THIS  FILE  WITHOUT  HAVING   ACCEPTED  THE  TERMS  OF   THE    */
  29. /*    BINKLEYTERM  LICENSING AGREEMENT,  OR SUCH OTHER  AGREEMENT AS YOU    */
  30. /*    ARE ABLE TO REACH WITH THE AUTHORS.                                   */
  31. /*                                                                          */
  32. /*                                                                          */
  33. /*    The Authors can be reached at the following addresses:                */
  34. /*                                                                          */
  35. /*    Robert C. Hartman                      Vincent E. Perriello           */
  36. /*    Spark Software                         VEP Software                   */
  37. /*    427-3 Amherst Street                   111 Carroll Street             */
  38. /*    CS2032, Suite 232                      Naugatuck, CT 06770            */
  39. /*    Nashua, NH 03061                                                      */
  40. /*                                                                          */
  41. /*    FidoNet 1:132/101                      FidoNet 1:141/491              */
  42. /*    Data    (603) 888-8179                 Data    (203) 729-7569         */
  43. /*                                                                          */
  44. /*    Please feel free to contact us at any time to share your comments     */
  45. /*    about our software and/or licensing policies.                         */
  46. /*                                                                          */
  47. /*--------------------------------------------------------------------------*/
  48.  
  49. #include <stdio.h>
  50. #include <signal.h>
  51. #include <ctype.h>
  52. #include <conio.h>
  53. #include <stdlib.h>
  54. #include <string.h>
  55. #include <sys/types.h>
  56. #include <sys/stat.h>
  57.  
  58. #ifdef __TURBOC__
  59. #include <alloc.h>
  60. #else
  61. #include <malloc.h>
  62. #endif
  63.  
  64. typedef unsigned bit;
  65. typedef unsigned int word;
  66. typedef unsigned char byte;
  67.  
  68. struct parse_list {
  69.         int p_length;
  70.         char *p_string;
  71.         };
  72.  
  73. /*--------------------------------------------------------------------------*/
  74. /* The following is excerpted from the control structures used by Opus 1.10 */
  75. /* as it is currently implemented. The only part that really concerns BTCTL */
  76. /* is that part of the _PRM structure that contains the version number and  */
  77. /* the network address. Only those parts are actually handled by this code. */
  78. /* We suspect that no changes will be made in that part of the structure    */
  79. /* between now and the release of Opus 1.10. If I were you, I would make    */
  80. /* no such assumptions about the rest.                                      */
  81. /*--------------------------------------------------------------------------*/
  82.  
  83. #define  THIS_CTL_VERSION  16       /* PRM structure version number         */
  84.  
  85. #define CTLSIZE 1
  86. #define OFS     char*
  87.  
  88. #define  MAX_EXTERN         8       /* max. number of external programs     */
  89. #define  MAXCLASS          12       /* number of possible priv levels       */
  90. #define  ALIAS_CNT         15       /* number of matrix addresses           */
  91.  
  92. /*--------------------------------------------------------------------------*/
  93. /* FIDONET ADDRESS STRUCTURE                                                */
  94. /*--------------------------------------------------------------------------*/
  95. typedef struct _ADDRESS
  96.    {
  97.    word  Zone;
  98.    word  Net;
  99.    word  Node;
  100.    word  Point;
  101.    } ADDR;
  102.  
  103. /*--------------------------------------------------------------------------*/
  104. /* Attributes of a given class of users                                     */
  105. /*--------------------------------------------------------------------------*/
  106. struct   class_rec
  107.    {
  108.    byte  ClassPriv;
  109.    byte  class_fill;
  110.    int   max_time;      /* max cume time per day         */
  111.    int   max_call;      /* max time for one call         */
  112.    int   max_dl;        /* max dl bytes per day          */
  113.    word  ratio;         /* ul:dl ratio                   */
  114.    word  min_baud;      /* speed needed for logon        */
  115.    word  min_file_baud; /* speed needed for file xfer    */
  116.    };
  117.  
  118. /*--------------------------------------------------------------------------*/
  119. /* Registers to pass to a FOSSIL appendage                                  */
  120. /*--------------------------------------------------------------------------*/
  121. struct _FOSREGS
  122.    {
  123.    word  ax;
  124.    word  bx;
  125.    word  cx;
  126.    word  dx;
  127.    };
  128.  
  129. /*--------------------------------------------------------------------------*/
  130. /* The format of the PRM file, VERSION 16                                   */
  131. /*                                                                          */
  132. /* THIS IS AN EXPLOSIVE STRUCTURE.  IT IS SUBJECT TO CHANGE WITH NO NOTICE. */
  133. /*                                                                          */
  134. /* Offsets to the following item(s) are guaranteed:                         */
  135. /*                                                                          */
  136. /*      byte   version;        /* OFFSET 0, all versions                    */
  137. /*      byte   task_num;       /* OFFSET 1, 16+                             */
  138. /*                                                                          */
  139. /*--------------------------------------------------------------------------*/
  140.  
  141. struct _PRM
  142.    {
  143.                /*-----------------------------------------------------------*/
  144.                /* DATA                                                      */
  145.                /*-----------------------------------------------------------*/
  146.          byte  version;        /* for safety                          STABLE*/
  147.          byte  task_num;       /* for multi-tasking systems           STABLE*/
  148.          ADDR  alias[ALIAS_CNT];
  149.  
  150.          byte  video;          /* 0=Dos, 1=Fossil 2=IBM                     */
  151.          byte  testmode;       /* input from keyboard, not modem            */
  152.  
  153.          word  carrier_mask;
  154.          word  handshake_mask;
  155.          word  max_baud;       /* fastest speed we can use                  */
  156.          word  com_port;       /* Com1=0, Com2=1, FF=keyboard               */
  157.  
  158.          byte  multitasker;    /* flag for DoubleDos (see below)            */
  159.          byte  mailer_type;    /* 0=Opus, 1=load external, 2=call external  */
  160.  
  161.          byte  ModemFlag;      /* (See MODEM FLAG below)                    */
  162.          byte  LogFlag;        /* (See LOG FLAG below)                      */
  163.  
  164.          byte  StyleFlag;      /* (See STYLE FLAG below)                    */
  165.          byte  FWDflag;        /* Bits to control IN TRANSIT messages       */
  166.  
  167.          byte  Flags;          /* See "FLAGS" below                         */
  168.          byte  Flags2;         /* See "FLAGS 2" below                       */
  169.  
  170.          byte  edit_exit;      /* ERRORLEVEL to use if Matrix area changed  */
  171.          byte  exit_val;       /* ERRORLEVEL to use after caller            */
  172.  
  173.          byte  crashexit;      /* non-zero= ErrorLevel exit                 */
  174.          byte  arc_exit;       /* ErrorLevel for after incomming ARCmail    */
  175.  
  176.          byte  echo_exit;      /* ERRORLEVEL for after inbound echomail     */
  177.          byte  UDB_Flags;      /* User data base flags                      */
  178.  
  179.          word  min_baud;       /* minimum baud to get on-line               */
  180.          word  color_baud;     /* min baud for graphics                     */
  181.          word  date_style;     /* Used for FILES.BBS display                */
  182.  
  183.          byte  logon_priv;     /* Access level for new users                */
  184.          byte  seenby_priv;    /* Min priv to see SEEN_BY line              */
  185.  
  186.          byte  ctla_priv;      /* Priv to see CONTROL-A lines in messages   */
  187.          byte  FromFilePriv;   /* Priv. for doing message from file         */
  188.  
  189.          byte  AskPrivs[16];   /* Array of privs. for message attr ask's    */
  190.          byte  AssumePrivs[16];/* Array of privs. for message attr assume's */
  191.  
  192.          word  logon_time;     /* time to give for logons                   */
  193.  
  194.          word  matrix_mask;
  195.          
  196.          word  MinNetBaud;     /* minimum baud rate for remote netmail      */
  197.          word  MaxJanusBaud;   /* fastest baud to use Ianus                 */
  198.  
  199.          struct class_rec class[MAXCLASS];
  200.          struct _FOSREGS FosRegs[10];
  201.  
  202.          word  F_Reward;       /* File upload time reward percentage        */
  203.  
  204.          word  last_area;      /* Highest msg area presumed to exist        */
  205.          word  last_farea;     /* Highest file area presumed to exist       */
  206.  
  207.          word  PRM_FILL3[17];
  208.  
  209.  
  210.                /*-----------------------------------------------------------*/
  211.                /* OFFSETS                                                   */
  212.                /*-----------------------------------------------------------*/
  213.  
  214.                                /*-------------------------------------------*/
  215.                                /* MODEM COMMAND STRINGS                     */
  216.                                /*-------------------------------------------*/
  217.          OFS   MDM_Init;       /* modem initialization string               */
  218.          OFS   MDM_PreDial;    /* modem dial command sent before number     */
  219.          OFS   MDM_PostDial;   /* modem command sent after dialed number    */
  220.          OFS   MDM_LookBusy;   /* mdm cmd to take modem off hook            */
  221.  
  222.                                /*-------------------------------------------*/
  223.                                /* PRIMROSE PATHS                            */
  224.                                /*-------------------------------------------*/
  225.          OFS   misc_path;      /* path to BBS/GBS files                     */
  226.          OFS   sys_path;       /* path to SYSTEM?.BBS files                 */
  227.          OFS   temppath;       /* place to put temporary files              */
  228.          OFS   net_info;       /* path to NODELIST files                    */
  229.          OFS   mailpath;       /* place to put received netmail bundles     */
  230.          OFS   filepath;       /* place to put received netmail files       */
  231.          OFS   hold_area;      /* path to pending outbound matrix traffic   */
  232.  
  233.                                /*-------------------------------------------*/
  234.                                /* DATA FILE NAMES                           */
  235.                                /*-------------------------------------------*/
  236.          OFS   user_file;      /* path/filename of User.Bbs                 */
  237.          OFS   sched_name;     /* name of file with _sched array            */
  238.          OFS   syl;            /* default system language file              */
  239.          OFS   usl;            /* default user language file                */
  240.  
  241.                                /*-------------------------------------------*/
  242.                                /* MISCELLANEOUS TEXT                        */
  243.                                /*-------------------------------------------*/
  244.          OFS   system_name;    /* board's name                              */
  245.          OFS   sysop;          /* sysop's name                              */
  246.          OFS   timeformat;
  247.          OFS   dateformat;
  248.          OFS   protocols[MAX_EXTERN]; /* external file protocol programs    */
  249.  
  250.                                /*-------------------------------------------*/
  251.                                /* BBS/GBS SUPPORT FILES                     */
  252.                                /*-------------------------------------------*/
  253.          OFS   logo;           /* first file shown to a caller              */
  254.          OFS   welcome;        /* shown after logon                         */
  255.          OFS   newuser1;
  256.          OFS   newuser2;
  257.          OFS   rookie;
  258.  
  259.          OFS   HLP_Editor;     /* Intro to msg editor for novices.          */
  260.          OFS   HLP_Replace;    /* Explain the Msg.Editor E)dit command      */
  261.          OFS   HLP_Inquire;    /* Explain the Msg. I)nquire command         */
  262.          OFS   HLP_Locate;     /* Explain the Files L)ocate command         */
  263.          OFS   HLP_Contents;   /* Explain the Files C)ontents command       */
  264.          OFS   HLP_OPed;       /* help file for the full-screen editor      */
  265.          OFS   OUT_Leaving;    /* Bon Voyage                                */
  266.          OFS   OUT_Return;     /* Welcome back from O)utside                */
  267.          OFS   ERR_DayLimit;   /* Sorry, you've been on too long...         */
  268.          OFS   ERR_TimeWarn;   /* warning about forced hangup               */
  269.          OFS   ERR_TooSlow;    /* explains minimum logon baud rate          */
  270.          OFS   ERR_XferBaud;   /* explains minimum file transfer baud rate  */
  271.          OFS   LIST_MsgAreas;  /* dump file... used instead of Dir.Bbs      */
  272.          OFS   LIST_FileAreas; /* dump file... used instead of Dir.Bbs      */
  273.         
  274.          OFS   FREQ_MyFiles;   /* file to send when FILES is file requested */
  275.          OFS   FREQ_OKList;    /* list of files approved for file requests  */
  276.          OFS   FREQ_About;     /* File Request: ABOUT file                  */
  277.  
  278.          OFS   OEC_Quotes;
  279.          OFS   byebye;         /* file displayed at logoff                  */
  280.          OFS   local_editor;   /* text editor to use in keyboard mode       */
  281.          OFS   barricade;
  282.          OFS   Files_BBS;      /* FILES.BBS filename override for CD ROM    */
  283.          OFS   mailer;         /* full external mailer command              */
  284.          OFS   common;         /* File with data common to all tasks        */
  285.  
  286.          OFS   OFS_Filler[13];
  287.  
  288.                /*-----------------------------------------------------------*/
  289.                /* Log_Name must always be the last offset in this struct    */
  290.                /* because Bbs_Init uses that symbol to flag the end of      */
  291.                /* the offsets.                                              */
  292.                /*-----------------------------------------------------------*/
  293.          OFS   log_name;       /* name of the log file                      */
  294.  
  295.  
  296.                /*-----------------------------------------------------------*/
  297.                /* Big blob of stuff                                         */
  298.                /* It's a sequence of null-terminated character arrays...    */
  299.                /* pointed-to by the offsets (above).                        */
  300.                /*-----------------------------------------------------------*/
  301.          char  buf[CTLSIZE];
  302.    };
  303.  
  304. /* Stuff used later on here */
  305.  
  306. void           main (void);
  307. void           errxit (char *);
  308. char           *fancy_str (char *);
  309. char           *add_backslash (char *);
  310. char           *delete_backslash (char *);
  311. char           *ctl_string (char *);
  312. char           *ctl_slash_string (char *);
  313. char           *skip_blanks (char *);
  314. void            parse_config (char *);
  315. void            b_initvars (void);
  316. void            b_defaultvars (void);
  317. int             parse (char *, struct parse_list *);
  318.  
  319. char           *BTCTL_ANN = "BTCtl - Revision 2.10\n\n";
  320. char           *config_name = "Binkley.Cfg";
  321. char           *BINKpath = NULL;
  322. int             pvtnet = 0;
  323. int             net_params = 0;
  324. int        Zone = 1;
  325.  
  326. /*--------------------------------------------------------------------------*/
  327. /* BTCTL                                                                    */
  328. /* Parse the BINKLEY.CFG file and write out a BINKLEY.PRM file (for use by  */
  329. /* OMMM) and a MAIL.SYS file (for use by FASTTOSS, SCANMAIL, SIRIUS, etc).  */
  330. /* If the environment variable BINKLEY exists use the path specified for    */
  331. /* ALL input and output files.                                              */
  332. /*--------------------------------------------------------------------------*/
  333.  
  334. /*--------------------------------------------------------------------------*/
  335. /* MAIL.SYS file structure                                                  */
  336. /*--------------------------------------------------------------------------*/
  337. struct _mail
  338. {
  339. int             pri_node;       /* Our node number                          */
  340. float           fudge;          /* Unknown/unused                           */
  341. int             rate;           /* Maximum baud rate                        */
  342. char            mailpath[80];   /* Path for incomming messages              */
  343. char            filepath[80];   /* Path for incomming files                 */
  344. int             pri_net;        /* Our network number                       */
  345. int             alt_node;       /* Alternate node number (mainly for HOSTS) */
  346. int             alt_net;        /* Alternate net number (mainly for HOSTS)  */
  347. };
  348.  
  349. struct _mail    mailsys;        /* MAIL.SYS used by SIRIUS  */
  350. struct _PRM     ctl;            /* where the .CTL stuff is  */
  351.  
  352. int             num_addrs = 0;
  353.  
  354. void main ()
  355. {
  356.    char           *envptr;
  357.    FILE           *stream;
  358.    char            temp[80];
  359.    char           *skip_blanks ();
  360.    struct stat     statbuf;
  361.    int             k;
  362.  
  363.    printf (BTCTL_ANN);
  364.  
  365.    b_initvars ();
  366.  
  367.    envptr = getenv ("BINKLEY");                  /* get path from environment */
  368.    if ((envptr != NULL)                          /* If there was one, and     */
  369.        && (stat (config_name,&statbuf) != 0))    /* No BINKLEY.CFG locally,   */
  370.       {
  371.       BINKpath = malloc (strlen (envptr) + 2);   /* make room for new */
  372.       strcpy (BINKpath, envptr);                 /* use BINKLEY as our path   */
  373.       add_backslash (BINKpath);
  374.       }
  375.  
  376.    parse_config ("Binkley.Evt");
  377.    parse_config (config_name);
  378.  
  379.    b_defaultvars ();
  380.  
  381.    /*
  382.     * Print out what we got.
  383.     */
  384.  
  385.    if (ctl.system_name != NULL)
  386.       printf ("System: %s\n",ctl.system_name);
  387.  
  388.    if (ctl.sysop != NULL)
  389.       printf ("Sysop:  %s\n",ctl.sysop);
  390.  
  391.    for (k = 0; k < ALIAS_CNT; k++)               /* And the alias list        */
  392.       {
  393.       if (!ctl.alias[k].Zone)
  394.          break;
  395.       printf ("Address %u:%u/%u.%u\n",
  396.                ctl.alias[k].Zone,
  397.                ctl.alias[k].Net,
  398.                ctl.alias[k].Node,
  399.                ctl.alias[k].Point);
  400.       }
  401.  
  402.    if (ctl.mailpath != NULL)
  403.       printf ("Net Mailpath %s\n",ctl.mailpath);
  404.  
  405.    if (ctl.filepath != NULL)
  406.       printf ("Net Filepath %s\n",ctl.filepath);
  407.  
  408.    printf ("\n");
  409.  
  410.    if (!net_params)
  411.       errxit ("Not enough information to establish Netmail session");
  412.  
  413.    /*
  414.     * Okay, we have the nodelist data from the BINKLEY.CFG file.
  415.     * Now write it into a BINKLEY.PRM file.
  416.     */
  417.  
  418.    if (BINKpath != NULL)                         /* If there was a BINKLEY,   */
  419.       {
  420.       strcpy (temp, BINKpath);                   /* use it here too           */
  421.       }
  422.    else
  423.       temp[0] = '\0';
  424.    strcat (temp, "Binkley.Prm");                 /* add in the file name      */
  425.  
  426.    if ((stream = fopen (temp, "wb")) == NULL)    /* OK, let's open the file   */
  427.       errxit ("Unable to open BINKLEY.PRM");
  428.    if (fwrite (&ctl, sizeof (ctl), 1, stream) != 1) /* Try to write data out  */
  429.       errxit ("Could not write control file data to BINKLEY.PRM");
  430.    fclose (stream);                              /* close output file         */
  431.    printf ("Version 16 Control file successfully written\n");
  432.    printf ("oMMM 1.30 or above is required to use it\n\n");
  433.  
  434.    /*
  435.     * BINKLEY.PRM now written. Let's write a MAIL.SYS file too.
  436.     */
  437.  
  438.    mailsys.pri_node = ctl.alias[0].Node;
  439.    mailsys.pri_net  = ctl.alias[0].Net;
  440.    mailsys.alt_node = ctl.alias[1].Node;
  441.    mailsys.alt_net  = ctl.alias[1].Net;
  442.    strcpy (mailsys.mailpath, ctl.mailpath);
  443.    strcpy (mailsys.filepath, ctl.filepath);
  444.  
  445.    if (BINKpath != NULL)                         /* If there was a BINKLEY,   */
  446.       {
  447.       strcpy (temp, BINKpath);                   /* use it here too           */
  448.       }
  449.    else
  450.       temp[0] = '\0';
  451.    strcat (temp, "Mail.Sys");                    /* add in the file name      */
  452.  
  453.    if ((stream = fopen (temp, "wb")) == NULL)    /* OK, let's open the file   */
  454.       errxit ("Could not open MAIL.SYS");        /* no file, no work to do    */
  455.    if (fwrite (&mailsys, sizeof (mailsys), 1, stream) != 1)
  456.       errxit ("Unable to write data to MAIL.SYS");  /* Try to write data out  */
  457.    fclose (stream);                              /* close output file         */
  458.    printf ("MAIL.SYS file successfully written\n"); /* Notify user of success */
  459. }
  460.  
  461. /**
  462.  ** b_initvars -- called before parse_config. Sets defaults that we want
  463.  ** to have set FIRST.
  464.  **/
  465.  
  466.  
  467. void b_initvars ()
  468. {
  469.    int k;
  470.  
  471.    ctl.version = 16;
  472.    for (k = 0; k < ALIAS_CNT; k++)               /* And the alias list        */
  473.       {
  474.       ctl.alias[k].Zone = ctl.alias[k].Net = 
  475.       ctl.alias[k].Node = ctl.alias[k].Point = 0;
  476.       }
  477.  
  478.    ctl.alias[0].Zone = 1;                        /* Make sure we have a zone  */
  479.    ctl.alias[0].Net = ctl.alias[0].Node = -1;    /* Default Fidonet address   */
  480.    ctl.alias[0].Point = 0;
  481.  
  482.    ctl.system_name = ctl.sysop = 
  483.    ctl.hold_area = ctl.mailpath = ctl.filepath = NULL;
  484. }
  485.  
  486. /**
  487.  ** b_defaultvars -- called after all parse_config passes complete.
  488.  ** sets anything not handled by parse_config to default if we know it.
  489.  **/
  490.  
  491.  
  492. void b_defaultvars ()
  493. {
  494.    /* Set up "point" address correctly if we can */
  495.    
  496.    if (ctl.alias[0].Point)
  497.       {
  498.       ctl.alias[0].Net   = pvtnet;
  499.       ctl.alias[0].Node  = ctl.alias[0].Point;
  500.       ctl.alias[0].Point = 0;
  501.       }
  502.  
  503.    /* If we have the minimum information to do netmail, set the flag */
  504.  
  505.    if ((ctl.alias[0].Zone  != 0)
  506.    &&  (ctl.alias[0].Net   != 0)
  507.    &&  (ctl.system_name    != NULL)
  508.    &&  (ctl.sysop          != NULL)
  509.    &&  (ctl.hold_area      != NULL)
  510.    &&  (ctl.filepath       != NULL)
  511.    &&  (ctl.mailpath       != NULL))
  512.       net_params = 1;
  513. }
  514.  
  515.  
  516. struct parse_list config_lines[] = {
  517.                                     {4,  "Zone"},
  518.                                     {6,  "System"},
  519.                                     {5,  "Sysop"},
  520.                                     {4,  "Boss"},
  521.                                     {5,  "Point"},
  522.                                     {3,  "Aka"},
  523.                                     {7,  "Address"},
  524.                                     {4,  "Hold"},
  525.                                     {7,  "NetFile"},
  526.                                     {7,  "NetMail"},
  527.                                     {7,  "Include"},
  528.                                     {10, "PrivateNet"},
  529.                                     {0, NULL}
  530. };
  531.  
  532.  
  533. void parse_config (config_file)
  534. char *config_file;
  535. {
  536.    FILE *stream;
  537.    char temp[256];
  538.    char *c;
  539.    int i;
  540.    int boss_net = 0;
  541.    int boss_node = 0;
  542.  
  543.    if (BINKpath != NULL)
  544.       sprintf (temp, "%s%s", BINKpath, config_file);
  545.    else
  546.       strcpy (temp, config_file);
  547.  
  548.    if ((stream = fopen (temp, "r")) == NULL)     /* OK, let's open the file   */
  549.       return;                                    /* no file, no work to do    */
  550.  
  551.    while ((fgets (temp, 255, stream)) != NULL)   /* Now we parse the file ... */
  552.       {
  553.       c = temp;                                  /* Check out the first char  */
  554.       if ((*c == '%') || (*c == ';'))            /* See if it's a comment
  555.                                                   * line */
  556.          continue;
  557.  
  558.       i = strlen (temp);                         /* how long this line is     */
  559.  
  560.       if (i < 3)
  561.          continue;                               /* If too short, ignore it   */
  562.  
  563.       c = &temp[--i];                            /* point at last character   */
  564.       if (*c == '\n')                            /* if it's a newline,        */
  565.          *c = '\0';                              /* strip it off              */
  566.  
  567.       switch (parse (temp, config_lines))
  568.          {
  569.          case 1:                                /* "Zone"         */
  570.             c = skip_blanks (&temp[4]);
  571.             Zone = atoi (c);
  572.             if (!Zone)                          /* if we didn't find a zone  */
  573.                printf ("Illegal zone: %s\n", &temp[4]);
  574.             break;
  575.  
  576.          case 2:                                /* "System"       */
  577.             ctl.system_name = ctl_string (&temp[6]);
  578.             break;
  579.  
  580.          case 3:                                /* "Sysop"        */
  581.             ctl.sysop = ctl_string (&temp[5]);
  582.             break;
  583.  
  584.          case 4:                                /* "Boss"         */
  585.             c = skip_blanks (&temp[4]);
  586.             sscanf (c, "%d/%d", &boss_net, &boss_node);
  587.             if (boss_net)
  588.                pvtnet = boss_net;
  589.             break;
  590.  
  591.          case 5:                                /* "Point"        */
  592.             i = 5;
  593.             goto address;
  594.  
  595.          case 6:                                /* "Aka"          */
  596.             i = 3;
  597.             goto address;
  598.  
  599.          case 7:                                /* "Address"      */
  600.             i = 7;
  601. address:
  602.             ctl.alias[num_addrs].Point = 0;
  603.             c = skip_blanks (&temp[i]);
  604.             i = sscanf (c, "%d:%d/%d.%d",
  605.                        &ctl.alias[num_addrs].Zone,
  606.                        &ctl.alias[num_addrs].Net,
  607.                        &ctl.alias[num_addrs].Node,
  608.                    &ctl.alias[num_addrs].Point);
  609.             if (i < 3)
  610.                {
  611.                i = sscanf (c, "%d/%d.%d", 
  612.                           &ctl.alias[num_addrs].Net,
  613.                           &ctl.alias[num_addrs].Node,
  614.                           &ctl.alias[num_addrs].Point);
  615.                if (i < 2)
  616.                    break;
  617.                ctl.alias[num_addrs].Zone = Zone;
  618.                }
  619.             Zone = ctl.alias[0].Zone;           /* First is real default */
  620.             ++num_addrs;
  621.             break;
  622.  
  623.          case 8:                               /* "Hold"         */
  624.             ctl.hold_area = ctl_slash_string (&temp[4]);
  625.             break;
  626.  
  627.          case 9:                               /* "NetFile"      */
  628.             ctl.filepath = ctl_slash_string (&temp[7]);
  629.             break;
  630.  
  631.          case 10:                              /* "NetMail"      */
  632.             ctl.mailpath = ctl_slash_string (&temp[7]);
  633.             break;
  634.  
  635.          case 11:                               /* "Include"      */
  636.             c = skip_blanks (&temp[7]);
  637.             parse_config (c);
  638.             break;
  639.  
  640.          case 12:                               /* "PrivateNet"   */
  641.             c = skip_blanks (&temp[10]);
  642.             pvtnet = atoi (c);
  643.             break;
  644.  
  645.          default:
  646.             break;
  647.          }
  648.       }
  649.    fclose (stream);                              /* close input file          */
  650.  
  651. }
  652.  
  653. int parse (input, list)
  654. char *input;
  655. struct parse_list list[];
  656.  
  657. {
  658.    int i;
  659.  
  660.    for (i = 0; list[i].p_length; i++)
  661.       {
  662.       if (strnicmp (input, list[i].p_string, list[i].p_length) == 0)
  663.          return (++i);
  664.       }
  665.    return (-1);
  666. }
  667.  
  668. void errxit (error)
  669. char           *error;
  670. {
  671.    printf ("\r\n%s\n", error);
  672.    exit (0);
  673. }
  674.  
  675. char *fancy_str (string)
  676. char *string;
  677. {
  678.    register int flag = 0;
  679.    char *s;
  680.  
  681.    s = string;
  682.  
  683.    while (*string)
  684.       {
  685.       if (isalpha (*string))                     /* If alphabetic,     */
  686.          {
  687.          if (flag)                               /* already saw one?   */
  688.             *string = tolower (*string);         /* Yes, lowercase it  */
  689.          else
  690.             {
  691.             flag = 1;                            /* first one, flag it */
  692.             *string = toupper (*string);         /* Uppercase it       */
  693.             }
  694.          }
  695.       else /* if not alphabetic  */ flag = 0;    /* reset alpha flag   */
  696.       string++;
  697.       }
  698.  
  699.    return (s);
  700. }
  701.  
  702. char *add_backslash (str)
  703. char           *str;
  704. {
  705.    char           *p;
  706.  
  707.    p = str + strlen (str) - 1;
  708.  
  709.    /* Strip off the trailing blanks */
  710.    while ((p >= str) && (isspace (*p)))
  711.       {
  712.       *p = '\0';
  713.       --p;
  714.       }
  715.  
  716.    /* Put a backslash if there isn't one */
  717.    if ((*p != '\\') && (*p != '/'))
  718.       {
  719.       *(++p) = '\\';
  720.       *(++p) = '\0';
  721.       }
  722.  
  723.    return (fancy_str (str));
  724. }
  725.  
  726. char *delete_backslash (str)
  727. char           *str;
  728. {
  729.    char           *p;
  730.  
  731.    p = str + strlen (str) - 1;
  732.  
  733.    if (p >= str)
  734.       {
  735.       /* Strip off the trailing blanks */
  736.       while ((p >= str) && (isspace (*p)))
  737.          {
  738.          *p = '\0';
  739.          --p;
  740.          }
  741.  
  742.       /* Get rid of backslash if there is one */
  743.       if ((p >=str) && ((*p == '\\') || (*p == '/')))
  744.          {
  745.          if ((p > str) && (*(p-1) != ':'))      /* Don't delete on root */
  746.             *p = '\0';
  747.          }
  748.       }
  749.  
  750.    return (fancy_str (str));
  751. }
  752. char           *ctl_string (source)             /* malloc & copy to ctl      */
  753. char           *source;
  754. {
  755.    char           *dest, *c;
  756.  
  757.    c = skip_blanks (source);    /* get over the blanks       */
  758.    dest = malloc (strlen (c) + 1);      /* allocate space for string */
  759.    strcpy (dest, c);            /* copy the stuff over       */
  760.    return (dest);               /* and return the address    */
  761. }
  762.  
  763. char           *ctl_slash_string (source)       /* malloc & copy to ctl      */
  764. char *source;
  765. {
  766.    char *dest, *c, *t;
  767.    int i;
  768.    struct stat buffer;
  769.  
  770.    c = skip_blanks (source);                     /* get over the blanks       */
  771.    i = strlen (c);                               /* get length of remainder   */
  772.    if (i < 1)                                    /* must have at least 1      */
  773.       return (NULL);                             /* if not, return NULL       */
  774.    t = dest = malloc (i+2);                      /* allocate space for string */
  775.    strcpy (dest, c);                             /* copy the stuff over       */
  776.    delete_backslash (dest);                      /* get rid of trailing stuff */
  777.    /* Check to see if the directory exists */
  778.    i = stat (dest, &buffer);
  779.    if (i || (!(buffer.st_mode & S_IFDIR)))
  780.       {
  781.       printf ("Directory '%s' does not exist!\n", dest);
  782.       printf ("  BinkleyTerm may fail to execute properly because of this!\n");
  783.       return(NULL);
  784.       }
  785.    add_backslash (dest);                         /* add the backslash         */
  786.    return (dest);                                /* return the directory name */
  787. }
  788.  
  789. char           *skip_blanks (string)
  790. char           *string;
  791. {
  792.    while (*string == ' ' || *string == '\t')
  793.       ++string;
  794.    return (string);
  795. }
  796.